原始题目:剑指 Offer 34. 二叉树中和为某一值的路径 (opens new window)

解题思路:

先序遍历:按照【根节点 | 左子树 | 右子树】顺序遍历树的全部节点。

路径记录:在先序遍历中,记录当前节点到根节点的路径。当路径为根节点到叶节点形成的路径路径的和为目标值时,将路径加入结果列表。

递归函数

  • **传递参数:**当前节点 rootroot,当前目标值 curSumcurSum,目标值 targettarget,当前节点到根节点的路径 pathpath

  • **终止条件:**当前节点 rootrootnullnull

  • 递推工作:

    1. 目标值更新:将当前节点值和 curSumcurSum 相加;
    2. 路径更新:将当前节点加入到 pathpath 中;
    3. 路径记录:当前节点 rootroot 为叶子节点 且 $curSum + root.val $ 等于 targettarget 时,将 pathpath 加入结果列表。
    4. 先序遍历:递归左子树和右子树。
    5. 路径恢复:向上回溯前,需要将当前节点从路径 pathpath 中删除。

代码:

private List<List<Integer>> ans = new ArrayList<>();

public List<List<Integer>> pathSum(TreeNode root, int target) {
    if (root == null) {
        return ans;
    }
    findPath(root, 0, target, new ArrayList<>());
    return ans;
}

private void findPath(TreeNode root, int curSum, int target, List<Integer> list) {
    if (root == null) {
        return;
    }
    curSum += root.val;
    list.add(root.val);
    if (curSum == target && root.left == null && root.right == null) {
            ans.add(new ArrayList<>(list));
            list.remove(list.size() - 1);
            return;
    }
    findPath(root.left, curSum, target, list);
    findPath(root.right, curSum, target, list);
    list.remove(list.size() - 1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

复杂度分析:

  • 时间复杂度O(N)O(N)NN 为树的节点总数。
  • 空间复杂度O(N)O(N):最差情况下,即树退化成链表,pathpath 存储所有的节点,使用 O(NO(N) 额外空间。
上次更新: 2023/10/15